<?php
// +----------------------------------------------------------------------
// | QSCMS
// +----------------------------------------------------------------------
// | Copyright (c)  2025 https://www.qqss.net All rights reserved.
// +----------------------------------------------------------------------
// | Licensed QSCMS is not free software, commercial use must purchase official license from official website to avoid unnecessary legal disputes.
// +----------------------------------------------------------------------
// | Author: Contract 990504246@qq.com
// +----------------------------------------------------------------------

namespace app\adminapi\controller\plugin;

use app\common\util\TokenAuth;
use app\common\exception\HttpResponseException;
use app\common\exception\HtmlResponseException;
use support\Response;

/**
 * Plugin management base controller
 * Specifically for token authentication of plugin management related functions
 */
class Base
{
    protected $user;
    protected $request;
    protected $authFailed = false;

    public function __construct()
    {
        $this->request = request();

        // Check authentication, handle directly if failed
        $authResult = $this->checkAdminAuth();
        if (!$authResult) {
            // Temporary debug info
            // error_log("PluginBase: Authentication failed");

            // If it's an HTML request, return error page
            if ($this->isHtmlRequest()) {
                $response = $this->showAuthErrorPage();
                // Use custom HtmlResponseException to correctly return HTML response
                throw new HtmlResponseException($response, trans('authentication_failed', [], 'plugin_base'));
            }

            // API request throws exception
            throw new HttpResponseException(401, ['msg' => trans('unauthorized_access', [], 'plugin_base')]);
        } else {
            // Temporary debug info
            // error_log("PluginBase: Authentication successful, user: " . ($this->user['username'] ?? 'unknown'));
        }
    }

    /**
     * Check administrator permissions (prioritize session, fallback to token)
     */
    protected function checkAdminAuth()
    {
        // Method 1: Try to get admin info from session, compatible with template pages
        if ($this->checkAdminSession()) {
            return true;
        }

        // Method 2: Fallback to token authentication, compatible with API interfaces
        if ($this->checkAdminToken()) {
            return true;
        }

        // Authentication failed
        return false;
    }

    /**
     * Check administrator session
     */
    protected function checkAdminSession()
    {
        try {
            // Use webman's session
            $session = $this->request->session();

            // Check if there's admin info in session
            $admin_user     = $session->get('admin_user');
            $session_expire = $session->get('admin_session_expire');

            if (!$admin_user || !$session_expire) {
                return false;
            }

            // Check if session is expired
            if (time() > $session_expire) {
                // Clear expired session
                $session->delete('admin_user');
                $session->delete('admin_session_expire');
                return false;
            }

            // Session is valid, set user info
            $this->user = $admin_user;
            return true;

        } catch (\Exception $e) {
            return false;
        }
    }

    /**
     * Check administrator token (fallback method)
     */
    protected function checkAdminToken()
    {
        try {
            // Get token, support multiple ways
            $token = $this->getTokenFromRequest();

            if (empty($token)) {
                return false;
            }

            // Parse token
            $user       = TokenAuth::parseToken('admin');
            $this->user = $user;
            return true;

        } catch (\Exception $e) {
            return false;
        }
    }

    /**
     * Determine if HTML page should be returned
     */
    protected function isHtmlRequest()
    {
        // Check if request path contains view-related paths
        $path = $this->request->path();
        if (strpos($path, '/view/') !== false) {
            return true;
        }

        // Check if format parameter specifies html
        $format = $this->request->get('format', $this->request->post('format', ''));
        if ($format === 'html') {
            return true;
        }

        // Default return false, use JSON response
        return false;
    }

    /**
     * Show friendly authentication error page
     */
    protected function showAuthErrorPage()
    {
        // Create HTML error page content
        $html = '<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>' . trans('access_restricted', [], 'plugin_base') . '</title>
    <style>
        body { font-family: Arial, sans-serif; margin: 0; padding: 50px; background: #f5f5f5; }
        .container { max-width: 600px; margin: 0 auto; background: white; padding: 40px; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); text-align: center; }
        .icon { font-size: 64px; color: #ff6b6b; margin-bottom: 20px; }
        h1 { color: #333; margin-bottom: 20px; }
        p { color: #666; margin-bottom: 30px; line-height: 1.6; }
        .btn { display: inline-block; padding: 12px 24px; background: #007bff; color: white; text-decoration: none; border-radius: 4px; transition: background 0.3s; }
        .btn:hover { background: #0056b3; }
    </style>
</head>
<body>
    <div class="container">
        <div class="icon">🔒</div>
        <h1>' . trans('access_restricted', [], 'plugin_base') . '</h1>
        <p>' . trans('login_required_message', [], 'plugin_base') . '</p>
    </div>
</body>
</html>';

        // Return Response object
        return new Response(401, ['Content-Type' => 'text/html; charset=utf-8'], $html);
    }

    /**
     * Get token from request
     */
    protected function getTokenFromRequest()
    {
        // 1. Get from Authorization header
        $authorization = $this->request->header('Authorization');
        if ($authorization && strpos($authorization, 'Bearer ') === 0) {
            return substr($authorization, 7);
        }

        // 2. Get from POST parameters
        $token = $this->request->post('access_token');
        if ($token) {
            return $token;
        }

        // 3. Get from GET parameters
        $token = $this->request->get('access_token');
        if ($token) {
            return $token;
        }

        return null;
    }

    /**
     * Return success response
     */
    protected function success($msg = null, $data = [])
    {
        if ($msg === null) {
            $msg = trans('operation_successful', [], 'plugin_base');
        }
        return json([
            'code' => 1,
            'msg'  => $msg,
            'data' => $data
        ]);
    }

    /**
     * Return error response
     */
    protected function error($msg = null, $code = 0)
    {
        if ($msg === null) {
            $msg = trans('operation_failed', [], 'plugin_base');
        }
        return json([
            'code' => $code,
            'msg'  => $msg,
            'data' => []
        ]);
    }

    /**
     * Render template
     */
    protected function render($template, $data = [])
    {
        // Add user info to template variables
        $data['admin_user'] = $this->user;

        return view($template, $data);
    }

    /**
     * Get main project API URL
     */
    protected function getMainApiUrl($path = '')
    {
        $mainApiUrl = config('site.marketplace.main_api_url');

        return rtrim($mainApiUrl, '/') . $path;
    }

    /**
     * Get user token
     */
    protected function getUserToken()
    {
        $loginFile = runtime_path() . '/plugin_cache/market_login.json';

        if (!file_exists($loginFile)) {
            return '';
        }
        $loginData = json_decode(file_get_contents($loginFile), true);
        if ($loginData && isset($loginData['token'])) {
            return $loginData['token'];
        }
        return '';
    }

}
